#include <iostream>
#include <memory>
#include <vector>
#include <string>

using namespace std;

/*  
    C++引入右值引用之后，可以通过右值引用，充分使用临时变量，或者即将不使用的变量即右值的资源，
    减少不必要的拷贝，提高效率。如下代码，均会产生临时变量：
    class RValue {
    };

    RValue get() {
        return RValue();
    }

    void put(RValue){}

    为了充分利用右值的资源，减少不必要的拷贝，C++11引入了:
    右值引用(&&)，移动构造函数，移动复制运算符，std::move。

*/

struct RValue {
private:
    string sources;
public:
    // 普通的析构函数
    ~RValue(){}

    // 普通的构造函数
	RValue():sources("hello!!!"){}

    // 移动构造函数
	RValue(RValue&& a) {
		sources = std::move(a.sources);
		cout<<"&& RValue"<<endl;
	}

	RValue(const RValue& a) {
		sources = a.sources;
		cout<<"& RValue"<<endl;
	}

    // 移动复制运算符
	void operator=(const RValue&& a) {
		sources = std::move(a.sources);
		cout<<"&& =="<<endl;
	}

	void operator=(const RValue& a) {
		sources = a.sources;
		cout<<"& =="<<endl;
	}
};

RValue get() {
    RValue a;

    // ruturn a的时候不会返回get()的局部变量a，因为局部变量a在栈中，
    // get()函数推出后局部变量a就失效了，因此要新构造一个临时RValue对象。
	return a;
}

void put(RValue){}

// 编译时要加上 -fno-elide-constructors 去点优化，才能看见效果
int main() {
    // 因为get()返回的是一个临时的RValue对象，所以根据临时的RValue对象
    // 新构造了一个RValue对象，作为a的值。
	RValue a = get();
        cout<<"---------------"<<endl;

    // 这里也是一样的，a是main()的局部变量，新构造一个临时RValue对象传给put()函数
	put(RValue());
	return 0;
}